/**
 * @Author       : Hejh(3010733382@qq.com)
 * @Version      : V1.0
 * @Date         : 2024-03-21 16:12:29
 * @Description  : 物理文件相关的接口验证器
 */

const Joi = require('joi')
const { IS_UNSAFE_INTEGER } = require('@/constants/joiSchema')
const {
  ERROR_SOURCE_CODE,
  ERROR_SYSTEM_CODE
} = require('@/constants/errorCode')

const { getFileInfo, combine } = require('@/utils/upload')
// const { updatePaper } = require('@/controller/paperController')
const R = require('@/models/Response')

const Mysequelize = require('@/models/index')

const fileSchema = {
  filename: Joi.string().min(2).max(255),
  fileId: Joi.string(),
  size: IS_UNSAFE_INTEGER,
  chunkIds: Joi.array().items(Joi.string()),
  parentId: IS_UNSAFE_INTEGER,
  file: Joi.any(),
  chunkId: Joi.string()
}

/**
 * @description 文件信息协商接口的参数验证
 * @param {*} ctx
 * @param {*} next
 * @returns
 */
module.exports.fileSharkValidate = async (ctx, next) => {
  const { fileId } = ctx.request.body
  // 看是否存储fileId对应的分片信息
  const info = await getFileInfo(fileId)

  // 说明已经传递了部分分片或者已经协商过了
  if (info) {
    if (!info.needs.length) {
      // 全部传完了
      const t = await Mysequelize.transaction()
      try {
        await combine(info)
        // if (ctx.request.url.includes('paper')) {
        //   await updatePaper(ctx, info, ctx.user.id, t)
        // }
        // await this.createFile(ctx, info, ctx.user.id, t)
        await t.commit()
        ctx.body = R.success({
          needs: info.needs
        })
        return
      } catch {
        await t.rollback()
        ctx.body = R.error(ERROR_SOURCE_CODE.FILE_COMBINE_ERROR)
      }
    }
    ctx.body = R.success({
      needs: info.needs
    })
    return
  }
  await next()
}

/**
 * @description 文件分片上传接口的参数验证
 * @param {*} ctx
 * @param {*} next
 * @returns
 */
module.exports.chunkUploadValidate = async (ctx, next) => {
  const schema = Joi.object({
    fileId: fileSchema.fileId.required(),
    chunkId: fileSchema.chunkId.required()
  }).validate(ctx.request.body)

  if (schema.error) {
    ctx.body = R.error(ERROR_SYSTEM_CODE.PARAMS_SCHEMA_ERROR)
    return
  }

  const { fileId, chunkId } = ctx.request.body

  // 这个接口单独调用时，需要确保已经进行了文件协商
  let fileInfo = await getFileInfo(fileId)
  if (!fileInfo) {
    // 可能这个时候文件已经上传完成，可以看看fileId对应的hash是否存在
    ctx.body = R.error(ERROR_SOURCE_CODE.FILE_CHUNK_INFO_NO_ERROR)
    return
  }
  // 文件分片需属于本fileId
  if (!fileInfo.chunkIds.includes(chunkId)) {
    ctx.body = R.error(ERROR_SOURCE_CODE.FILE_CHUNK_ERROR)
    return
  }
  if (!fileInfo.needs.includes(chunkId)) {
    // 此分片已经上传,分片重复上传
    ctx.body = R.success({
      needs: fileInfo.needs
    })
    return
  }
  await next()
}
